package com.feather.tenia.adapter;

import java.sql.DatabaseMetaData;

import com.feather.common.data.Column;
import com.feather.common.data.ColumnCollection;
import com.feather.common.data.MetaAdapter;
import com.feather.common.data.simple.SimpleColumnCollection;
import com.feather.tenia.ProcedureMeta;

/**
 * @author flogyin
 */
public abstract class ProcedureMetaAdapter extends MetaAdapter implements ProcedureMeta {
	private static final long	serialVersionUID	= 1L;

	protected short				type;
	protected ColumnCollection	columns				= new SimpleColumnCollection();
	protected String			callSql;

	@Override
	public short getType() {
		return this.type;
	}

	@Override
	public void setType(short type) {
		this.type = type;
	}

	@Override
	public ColumnCollection getColumns() {
		return this.columns;
	}

	@Override
	public String getPrintName() {
		StringBuilder builder = new StringBuilder();

		String name = getName();
		if (name != null && name.trim().length() > 0) {
			String schema = getSchema();
			String catalog = getCatalog();

			if (catalog != null) {
				builder.append(catalog);
				if (builder.length() > 0) {
					builder.append(".");
				}
			}
			if (schema != null) {
				builder.append(schema);
				if (builder.length() > 0) {
					builder.append(".");
				}
			}
			builder.append(name);
		}

		String str = builder.toString();
		return str.length() > 0 ? str : null;
	}

	@Override
	public String getCallName() {
		return getOriginal();
	}

	@Override
	public String getCallSql() {
		if (this.callSql == null) {
			StringBuilder sqlBuilder = new StringBuilder();
			sqlBuilder.append("{call ");
			sqlBuilder.append(getCallName());

			StringBuilder paramBuilder = new StringBuilder();
			int columnsCount = this.columns.getCount();
			boolean hasParam = false;
			for (int i = 0; i < columnsCount; i++) {
				Column column = this.columns.get(i);
				if (column.getOrdinal() <= 0) {
					continue;
				}
				// if (column == null) {
				// throw new RuntimeException("Invalid parameter: "+ pName);
				// }
				switch (column.getType()) {
					case DatabaseMetaData.procedureColumnReturn: {
						sqlBuilder.insert(1, "?=");
						break;
					}
					case DatabaseMetaData.procedureColumnIn:
					case DatabaseMetaData.procedureColumnOut:
					case DatabaseMetaData.procedureColumnInOut: {
						if (hasParam) {
							paramBuilder.append(",");
						}
						paramBuilder.append("?");
						hasParam = true;
						break;
					}
				}
			}

			if (hasParam) {
				sqlBuilder.append("(");
				sqlBuilder.append(paramBuilder.toString());
				sqlBuilder.append(")");
			} else {
				if (hasBracket())
					sqlBuilder.append("()");
			}
			sqlBuilder.append("}");
			this.callSql = sqlBuilder.toString();
		}
		return this.callSql;
	}

	protected boolean hasBracket() {
		return true;
	}
}
